package com.delianna.bwt;

import java.util.Date;
import java.util.List;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.delianna.bwt.helpers.AppStatus;
import com.delianna.bwt.helpers.CommonHelper;
import com.delianna.bwt.helpers.TimeHelper;
import com.delianna.bwt.models.BWT;
import com.delianna.bwt.models.Port;

/**
 * @author Delio Castillo (jangeador@gmail.com)
 * 
 */

public class PortListActivity extends ListActivity {
	/** Called when the activity is first created. */
	// private ListView lv1;
	private BWT bwt;
	private static final String PREFS_NAME = "BWT_PREFS";
	private String startupPref;
	private boolean showOnlyFavorites;
	private String theme;
	private int refreshTime;
	private int requestCode;
	private long lastUpdate;

	@Override
	public void onCreate(Bundle savedInstanceState) {

		LoadPreferences();

		super.onCreate(savedInstanceState);

		Bundle data = getIntent().getExtras();

		bwt = data.getParcelable("com.delianna.bwt.models.BWT");

		if (bwt == null) {
			setContentView(R.layout.app_error);

			Button btnConn = (Button) findViewById(R.id.button1);

			View.OnClickListener connHandler = new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					if (AppStatus.getInstance(PortListActivity.this).isOnline(
							PortListActivity.this)) {

						Intent intent = new Intent(PortListActivity.this,
								RefreshDataActivity.class);
						startActivityForResult(intent, requestCode);
						finish();
					}
				}
			};
			btnConn.setOnClickListener(connHandler);
			return;
		}

		// SET THE VIEW
		setContentView(R.layout.main);

		// THIS DISPLAYS THE PORTS IN THE LIST VIEW
		updateDataOnScreen();

		this.getListView().setTextFilterEnabled(true);

		registerForContextMenu(this.getListView());

		// CHECK THE PREFERENCES, if there is a last viewed port go to it.
		if (startupPref.equals("LAST_VIEWED_PORT")) {
			String LastViewed = this.getSettingString("LAST_PORT_VIEWED");
			if (LastViewed != null) {
				Port p = bwt.getPort(LastViewed);
				if (p != null) {
					Intent i = new Intent(PortListActivity.this,
							PortDetailsActivity.class);
					i.putExtra("com.delianna.bwt.models.Port", p);
					startActivity(i);
				}
			}
		}

		updateIfNeeded();
	}

	private void updateIfNeeded() {
		// TODO Auto-generated method stub
		// Show last updated time
		long now = new Date().getTime();
		int minutesAgo = (int) ((now - this.lastUpdate) / 1000 / 60);
		Toast.makeText(this, getString(R.string.last_update_before_minutes) + " " + minutesAgo + " " + getString(R.string.last_update_after_minutes),
				Toast.LENGTH_LONG).show();
		
		if (refreshTime > 0 && (refreshTime - 1) < minutesAgo){
			updateData();
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Log.d("CheckStartActivity", "onActivityResult and resultCode = "
				+ resultCode);
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == 1) {
			bwt = data.getExtras().getParcelable("com.delianna.bwt.models.BWT");
			onResume();
			Toast.makeText(this, "Update Success", Toast.LENGTH_LONG).show();
		} else {
			Toast.makeText(this, "Update Fail", Toast.LENGTH_LONG).show();
		}
	}

	@Override
	protected void onResume() {
		if (bwt != null) {
			this.LoadPreferences();
			this.updateDataOnScreen();
		}
		super.onResume();
	}

	private void LoadPreferences() {
		// Load Default Preferences or set preferences
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		startupPref = prefs.getString("startupPref", "LIST_OF_PORTS");
		this.showOnlyFavorites = prefs.getBoolean("favoritesPref", false);
		theme = prefs.getString("themePref", "dark");
		refreshTime = Integer.parseInt(prefs.getString("refreshPref", "30"));
		Log.v("Refresh Time", "r. time " + refreshTime);

		if (theme.equals("lite")) {
			setTheme(R.style.Lite);
		} else if (theme.equals("dark")) {
			setTheme(R.style.Dark);
		}

		this.lastUpdate = prefs.getLong("lastUpdate", 0);
	}

	private void updateDataOnScreen() {
		// Update Header fields
		TextView tvUpdateInfo = (TextView) findViewById(R.id.tvUpdateInfo);
		String lastUpdate = TimeHelper
				.adjustTimeToLocalTimeSDF(bwt.last_updated_date + " "
						+ bwt.last_updated_time + " EDT");
		tvUpdateInfo.setText(getString(R.string.last_updated) + ": "
				+ lastUpdate);
		
		List<Port> portsToDisplay;
		String favs = getFavoritePortNumbers();
		if (this.showOnlyFavorites && favs != null) {
			portsToDisplay = CommonHelper.SortPortList(bwt
					.getFavoritePorts(favs));
		} else {
			bwt.sortPorts();
			portsToDisplay = bwt.ports();
		}
		setListAdapter(new PortsAdapter(this, R.layout.port_row, portsToDisplay));
	}

	@Override
	protected void onListItemClick(android.widget.ListView l, View v,
			int position, long id) {
		try {
			// Toast.makeText(BWTPortListActivity.this,
			// "Selected Item is = " + l.getItemAtPosition(position),
			// Toast.LENGTH_LONG).show();

			Port p = (Port) l.getItemAtPosition(position);

			// call the detail activity

			Intent i = new Intent(PortListActivity.this,
					PortDetailsActivity.class);
			i.putExtra("com.delianna.bwt.models.Port", p);
			startActivity(i);

		} catch (Exception e) {
			Toast.makeText(PortListActivity.this, e.toString(),
					Toast.LENGTH_LONG).show();
		}
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		if (v == this.getListView()) {
			AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
			ListView item = (ListView) v;
			Port p = (Port) item.getItemAtPosition(info.position);
			menu.setHeaderTitle(p.port_name);
			if (!isFavorite(p.port_number)) {
				menu.add(0, 0, 0, R.string.add_favorite);
			} else {
				menu.add(0, 1, 1, R.string.remove_favorite);
			}
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
				.getMenuInfo();
		Port p = (Port) this.getListAdapter().getItem(info.position);
		String portNumber = p.port_number;
		int choice = item.getItemId();

		// Add or remove the port from favorites
		switch (choice) {
		case 0:
			this.addPortAsFavorite(portNumber);
			break;
		case 1:
			this.removePortAsFavorite(portNumber);
			break;
		}
		return true;
	}

	class PortsAdapter extends ArrayAdapter<Port> {

		int resource;
		String response;
		Context context;

		// Initialize adapter
		public PortsAdapter(Context context, int resource, List<Port> items) {
			super(context, resource, items);
			this.resource = resource;

		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			LinearLayout portView;
			// Get the current alert object
			Port po = getItem(position);

			// Inflate the view
			if (convertView == null) {
				portView = new LinearLayout(getContext());
				String inflater = Context.LAYOUT_INFLATER_SERVICE;
				LayoutInflater vi;
				vi = (LayoutInflater) getContext().getSystemService(inflater);
				vi.inflate(resource, portView, true);
			} else {
				portView = (LinearLayout) convertView;
			}
			// Get the text boxes from the listitem.xml file
			TextView tvPortName = (TextView) portView
					.findViewById(R.id.lblportname);
			TextView tvPortDetail = (TextView) portView
					.findViewById(R.id.lblportdetail);
			ImageView icon = (ImageView) portView.findViewById(R.id.icon);

			// Assign the appropriate data from our alert object above
			tvPortName.setText(po.port_name);
			tvPortDetail.setText(po.crossing_name);

			if (po.border.equals("Canadian Border")) {
				icon.setImageResource(R.drawable.canada_48);
			} else if (po.border.equals("Mexican Border")) {
				icon.setImageResource(R.drawable.mexico_48);
			}

			return portView;
		}

	}

	private String getSettingString(String key) {
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
		String value = settings.getString(key, null);
		return value;
	}

	private String getFavoritePortNumbers() {
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
		String value = settings.getString("FAVORITE_PORTS", null);
		return value;
	}

	private void addPortAsFavorite(String portNumber) {
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

		String rawFavoritePortNumbers = getFavoritePortNumbers();

		if (rawFavoritePortNumbers == null) {
			// setting does not exist add it and go
			rawFavoritePortNumbers = portNumber;
		} else {
			rawFavoritePortNumbers += "," + portNumber;
		}
		SharedPreferences.Editor editor = settings.edit();
		editor.putString("FAVORITE_PORTS", rawFavoritePortNumbers);
		// Commit the edits!
		editor.commit();
	}

	private void removePortAsFavorite(String portNumber) {
		SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

		String rawFavoritePortNumbers = getFavoritePortNumbers();
		String[] arrFavoritePortNumbers = rawFavoritePortNumbers.split(",");
		String newFavorites = "";

		for (int i = 0; i < arrFavoritePortNumbers.length; i++) {
			if (!arrFavoritePortNumbers[i].equals(portNumber)) {
				// Only if the port is not in the favorites
				// add to the raw string
				newFavorites += arrFavoritePortNumbers[i] + ",";
			}
		}
		if (newFavorites.length() > 2)
			newFavorites = newFavorites.substring(0, newFavorites.length() - 1);

		SharedPreferences.Editor editor = settings.edit();
		if (newFavorites.length() > 2) {
			editor.putString("FAVORITE_PORTS", newFavorites);
		} else {
			editor.remove("FAVORITE_PORTS");
		}
		// Commit the edits!
		editor.commit();

		// THIS DISPLAYS THE PORTS IN THE LIST VIEW
		updateDataOnScreen();
	}

	private boolean isFavorite(String portNumber) {
		boolean isFav = false;

		String rawFavoritePortNumbers = getFavoritePortNumbers();
		if (rawFavoritePortNumbers != null) {
			String[] arrFavoritePortNumbers = rawFavoritePortNumbers.split(",");

			for (int i = 0; i < arrFavoritePortNumbers.length; i++) {
				if (arrFavoritePortNumbers[i].equals(portNumber)) {
					// The port is in in the favorites
					// add to the raw string
					isFav = true;
					break;
				}
			}
		}
		return isFav;
	}

	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.portlist_menu, menu);
		return true;
	}

	private void updateData() {
		Intent intent = new Intent(PortListActivity.this,
				RefreshDataActivity.class);
		startActivityForResult(intent, requestCode);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.refresh:
			updateData();
			break;

		case R.id.favs:

			// Toggle SetFavorites
			SharedPreferences prefs = PreferenceManager
					.getDefaultSharedPreferences(this);
			SharedPreferences.Editor editor = prefs.edit();
			if (showOnlyFavorites)
				item.setIcon(R.drawable.star_on);
			else
				item.setIcon(R.drawable.star_off);
			showOnlyFavorites = !showOnlyFavorites;
			editor.putBoolean("favoritesPref", showOnlyFavorites);
			// Commit the edits!
			editor.commit();

			updateDataOnScreen();

			break;

		case R.id.settings:
			// Call Settings
			Intent settingsActivity = new Intent(getBaseContext(),
					SettingsActivity.class);
			startActivity(settingsActivity);
			break;
		}
		return true;
	}

	public boolean onPrepareOptionsMenu(final Menu menu) {
		if (this.showOnlyFavorites) {
			menu.findItem(R.id.favs).setTitle(R.string.show_all);
			menu.findItem(R.id.favs).setIcon(R.drawable.star_off);
		} else {
			menu.findItem(R.id.favs).setTitle(R.string.show_favs_only);
			menu.findItem(R.id.favs).setIcon(R.drawable.star_on);
		}

		return super.onPrepareOptionsMenu(menu);
	}
}